﻿(function ($) {
    'use strict';

    var Affix = function (element, options) {
        this.options = $.extend({}, Affix.DEFAULTS, $(element).data(), options)
        if (!this.options.target || $(this.options.target).css('overflow') != "auto") this.options.target = window;
        this.$target = $(this.options.target)
          .on('scroll.lgb.affix.data-api', $.proxy(this.checkPosition, this))
          .on('click.lgb.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))

        this.$element = $(element)
        if (this.options.root != '') this.$spy = this.$element.parents(this.options.root).find(this.options.spy)
        else this.$sky = $(this.options.spy)
        this.checkPosition()
    }

    Affix.VERSION = '1.0'

    Affix.DEFAULTS = {
        target: window,
        spy: '',
        root: '',
        offsetTop: 0,
        offsetBottom: 0
    }

    Affix.RESET = 'affix affix-top affix-bottom'

    Affix.prototype.checkPosition = function () {
        if (!this.$element.is(':visible')) return

        var height = this.$element.height()
        var offsetTop = this.options.target == window ? 0 : this.$target.offset().top

        var affix = this.getState(height, offsetTop)
        var affixType = 'affix' + (affix ? '-' + affix : '')
        this.$element.removeClass(Affix.RESET).addClass(affixType)
    }

    Affix.prototype.checkPositionWithEventLoop = function (element) {
        setTimeout($.proxy(this.checkPosition, this), 1)
    }

    Affix.prototype.getState = function (height, offsetTop) {
        var scrollTop = this.$target.scrollTop();
        var spyHeight = this.$spy.height()
        var position = this.$spy.offset()

        if (this.options.target == window) {
            if (position.top - scrollTop - height > 0) return 'top';
            return position.top + spyHeight - scrollTop - height - this.options.offsetBottom < 0 ? 'bottom' : false;
        }
        else {
            if (position.top - offsetTop - height - this.options.offsetTop > 0) return 'top';
            return position.top + spyHeight - offsetTop - this.options.offsetBottom < 0 ? 'bottom' : false;
        }
    }

    function Plugin(option) {
        return this.each(function () {
            var $this = $(this);
            if ($.browser.versions.mobile) $this.addClass('mobile')
            var data = $this.data('lgb.Affix');
            var options = typeof option == 'object' && option;
            if (!data) $this.data('lgb.Affix', (data = new Affix(this, options)));
        })
    }

    $.fn.lgbAffix = Plugin;
    $.fn.lgbAffix.Constructor = Affix;
    $(function () {
        $('[data-toggle="LgbAffix"]:visible').lgbAffix();
    });
})(jQuery);